/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;

import java.util.Properties;

import phoside.model.PhosideModelManager;

import phoside.util.StaticFinalValues;

/**
 *
 * @author gjj
 */
public final class PhosideInit {

    public static void init() {
        initializeModels();
    }

    private static String globalPropsVersion = "1";

    public final static File baseDir = new File(".");

    public final static File resourceDir = new File(StaticFinalValues.RESOURCEDIR);
    public final static File matrixDir = new File(resourceDir, StaticFinalValues.MATRIX);

    public final static File thirdPartyDir = new File(StaticFinalValues.THIRDPARTYDIR);

    public final static File modelDir;
    static {
        modelDir = new File(StaticFinalValues.MODELDIR);
        if (!modelDir.exists()) {
            if (!modelDir.mkdir()) {

            }
        }
    }

    public final static File propsDir;
    static {
        propsDir = new File(StaticFinalValues.PROPSDIR);
        if (!propsDir.exists()) {
            if (!propsDir.mkdir()) {

            }
        }
    }

    public final static File tmpDir;
    static {
        tmpDir = new File(StaticFinalValues.TMPDIR);
        if (!tmpDir.exists()) {
            if (!tmpDir.mkdir()) {

            }
        }
    }

    public static String defaultPath = baseDir.getPath();

    public static Properties globalProps;
    static {
        globalProps = new Properties();
        File gFile = new File(propsDir, StaticFinalValues.GLOBALPROPSFILE);
        boolean loaded = false;
        if (gFile.exists()) {
            try {
                globalProps.load(new FileInputStream(gFile));
                String version = globalProps.getProperty("Version");
                if (version!=null && globalPropsVersion.compareTo(version)==0) {
                    loaded = true;
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (!loaded) {
            Properties props = defaultGlobalProps();
            globalProps.putAll(props);
            try {
                globalProps.store(new FileOutputStream(gFile), "Global Properties");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static Properties trainingProps;
    static {
        trainingProps = defaultTrainingProps();
        File tFile = new File(propsDir, StaticFinalValues.TRAININGPROPSFILE);
        boolean save = true;
        if (tFile.exists()) {
            try {
                Properties props = new Properties();
                props.load(new FileInputStream(tFile));
                trainingProps.putAll(props);
                save = false;
            } catch (Exception e) {
                //e.printStackTrace();                
            }
        }

        if (save) {
            try {
                trainingProps.store(new FileOutputStream(tFile), "Training Properties");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }


    public static void initializeModels() {
        PhosideModelManager manager = Phoside.getModelManager();
        manager.clear();

        for (File file : modelDir.listFiles()) {
          if (file.isFile()) {
              String dir = file.getAbsolutePath();
              if (!dir.endsWith("."+StaticFinalValues.MODELAPPEDIX))
                  continue;

              try {
                  manager.addModelFile(file.getAbsolutePath());
              } catch (java.io.FileNotFoundException e) {
                  e.printStackTrace();
              }

//              try {
//                  System.out.println(file.getAbsolutePath());
//                  java.util.List<phoside.model.PhosideModel> model =
//                          new java.util.ArrayList(manager.loadModels(file.getAbsolutePath()));
//                  for (phoside.model.PhosideModel m : model) {
//
//                  }
//                  phoside.util.IOUtil.serializeObject(model, file.getAbsolutePath(), "gz");
//              } catch (Exception e) {
//                  e.printStackTrace();
//              }
          }
        }
    }

    public static Properties defaultGlobalProps() {
        Properties props = new Properties();
        props.setProperty("Version", globalPropsVersion);
        String thirdParty = PhosideInit.thirdPartyDir.getAbsolutePath();
        props.setProperty(StaticFinalValues.DISORDERPREDICTORVSL2,
                thirdParty+File.separator+"VSL2.jar");
        if (org.apache.commons.lang.SystemUtils.IS_OS_WINDOWS) {
            props.setProperty(StaticFinalValues.SVMTRAINDIR,
                    thirdParty+File.separator+"svm_learn.exe");
            props.setProperty(StaticFinalValues.SVMCLASSIFYDIR,
                    thirdParty+File.separator+"svm_classify.exe");
            props.setProperty(StaticFinalValues.BLASTCLUSTER,
                    thirdParty+File.separator+"blastclust.exe");
        } else { // linux
            props.setProperty(StaticFinalValues.SVMTRAINDIR,
                    thirdParty+File.separator+"svm_learn");
            props.setProperty(StaticFinalValues.SVMCLASSIFYDIR,
                    thirdParty+File.separator+"svm_classify");
            props.setProperty(StaticFinalValues.BLASTCLUSTER,
                    thirdParty+File.separator+"blastclust");
        }
        return props;
    }

    public static void saveTrainingProps() {
        File tFile = new File(propsDir, StaticFinalValues.TRAININGPROPSFILE);
        try {
            trainingProps.store(new FileOutputStream(tFile), "Training Properties");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Properties defaultTrainingProps() {
        Properties props = new Properties();
        props.setProperty(StaticFinalValues.SVMPARAMETERS,"-t 2 -g 1 -c 10 -m 256");

        props.setProperty(StaticFinalValues.NOOFBOOTS,"2000");
        props.setProperty(StaticFinalValues.NOOFCLASSIFIERS,"5");

        props.setProperty(StaticFinalValues.NEGATIVECONTROLSIZE, "10000");

        props.setProperty(StaticFinalValues.USEKNNFEATURES,"true");
        props.setProperty(StaticFinalValues.SUBSTITUTIONMATRIX,"blosum62");
        props.setProperty(StaticFinalValues.KNNWINDOWSIZE,"13");
        props.setProperty(StaticFinalValues.KNNNEIGHBORSIZES, "0.25,0.5,1,2,4");

        props.setProperty(StaticFinalValues.USEDISORDERFEATURES,"true");
        props.setProperty(StaticFinalValues.DISORDERWINDOWSIZES,"1,5,13");

        props.setProperty(StaticFinalValues.USEFREQUENCYFEATURES,"true");
        props.setProperty(StaticFinalValues.FREQUENCYWINDOWSIZE,"13");
        props.setProperty(StaticFinalValues.FREQUENCYFEATURENUMBER,"10");

        props.setProperty(StaticFinalValues.PADDINGTERMINALS,"true");
        return props;
    }
}
